package org.hzz.spring.code.extensions;

import lombok.extern.slf4j.Slf4j;
import org.hzz.spring.code.context.BeanElement;
import org.hzz.spring.code.context.PkmerContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.annotation.AnnotatedElementUtils;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * @author 胖卡
 * @version 1.0.0
 * @date 2024/8/2
 */
@Slf4j
public class SpringPkmerExecutor implements ApplicationContextAware, SmartInitializingSingleton {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringPkmerExecutor.applicationContext = applicationContext;
    }

    @Override
    public void afterSingletonsInstantiated() {
        log.info("所有bean已经初始化");

        String[] beanNames = applicationContext.getBeanNamesForType(Object.class, false, true);

        for (String beanName : beanNames) {
            if ("userService".equals(beanName)) {
                Object bean = applicationContext.getBean(beanName);
                Map<Method, Pkmer> methodPkmerMap = MethodIntrospector.selectMethods(
                        bean.getClass(),
                        (MethodIntrospector.MetadataLookup<Pkmer>) method -> AnnotatedElementUtils.findMergedAnnotation(method, Pkmer.class)
                );


                for (Map.Entry<Method, Pkmer> entry : methodPkmerMap.entrySet()) {
                    Method method = entry.getKey();
                    Pkmer pkmerAnnotation = entry.getValue();
                    // todo 任何业务，比如xxl_job是用netty来进行远程通信
                    PkmerContext.setElement(
                            pkmerAnnotation.value(),
                            BeanElement.of(bean, method)
                    );
                }

            }
        }
    }
}
